import java.io.FileWriter;
import java.io.IOException;
import java.io.Writer;
import java.util.HashMap;
import java.util.Vector;
/*
public class Evaluator {
	
	private double logb(double a, double b) 
	{
		return Math.log(a) / Math.log(b);
	}

	private double log2(double a) 
	{
		return logb(a, 2);
	}
	
	
	public void CalcMeasurements(SearchResults gt, SearchResults actual, Writer report_writer ) throws IOException
	{
		//query id, percision at k
		HashMap<Integer, Vector<Float>> percision_at_k_per_query = new HashMap<Integer, Vector<Float>>();		
		
		//query id , bit map of correct docs
		HashMap<Integer, Vector<Boolean>> correct_docs_bitmap = new HashMap<Integer, Vector<Boolean>>();
		report_writer.write("query,p@5,p@10\n");
		for (int q_i : gt.mResults.keySet()) 
		{
			Vector<Float> query_percision_at_k = new Vector<Float>();
			Vector<Boolean> bitmap = new Vector<Boolean>();
			if (actual.mResults.containsKey(q_i))
			{
				Vector<Integer> all_gt_for_query_at_k = new Vector<Integer>(gt.mResults.get(q_i));
				
				
				int rank = 1;
				int relevant_documents = 0;
				
				
				for(int doc_id : actual.mResults.get(q_i))
				{
					if(all_gt_for_query_at_k.contains(doc_id))
					{
						++relevant_documents;
						bitmap.add(true);
					}
					else
					{
						bitmap.add(false);
					}
					
					query_percision_at_k.add((float)relevant_documents/(float)rank);
					
					++rank;
				}					
			}
			percision_at_k_per_query.put(q_i, query_percision_at_k);
			correct_docs_bitmap.put(q_i, bitmap);
		}
		
		HashMap<Integer, Float> percision_at_5 = new HashMap<Integer, Float>();
		HashMap<Integer, Float> percision_at_10 = new HashMap<Integer, Float>();
		for(int q_i : percision_at_k_per_query.keySet())
		{
			float percision_at_5_for_query = 0; 
			float percision_at_10_for_query = 0;
			if(percision_at_k_per_query.size() > 9 )
			{
				percision_at_5_for_query  = percision_at_k_per_query.get(q_i).get(4);
				percision_at_10_for_query = percision_at_k_per_query.get(q_i).get(9);				
			}
			else if (percision_at_k_per_query.size() > 4 )//but still less than 10
			{
				percision_at_5_for_query = percision_at_k_per_query.get(q_i).get(4);
				percision_at_10_for_query = percision_at_k_per_query.get(q_i).get(4);
				
			}
			else //less than five elements
			{
				int last_elmenet_index =  percision_at_k_per_query.size() -1 ;
				percision_at_5_for_query = percision_at_k_per_query.get(q_i).get(last_elmenet_index);				
				percision_at_10_for_query = percision_at_k_per_query.get(q_i).get(last_elmenet_index);				
			}
			percision_at_5.put(q_i, percision_at_5_for_query);
			percision_at_10.put(q_i, percision_at_10_for_query);
			report_writer.write(q_i+","+percision_at_5_for_query+","+ percision_at_10_for_query+"\n");
			
		}
		
		HashMap<Integer, Float> average_percision_per_query = new HashMap<Integer, Float>();
		for(int q_i : percision_at_k_per_query.keySet())
		{			
			Vector<Boolean> bitmap = correct_docs_bitmap.get(q_i);		
			Vector<Float> query_percision_at_k = percision_at_k_per_query.get(q_i);
			
			float average = 0;
			int number_of_truth = 0;
			for(int i  =0;i < correct_docs_bitmap.get(q_i).size();++i)
			{
				if(bitmap.get(i))
				{
					average  =  average + query_percision_at_k.get(i);
					++number_of_truth;	
				}			}
			if(number_of_truth > 0)
			{
				average = average / (float)number_of_truth;	
			}
			
			
			average_percision_per_query.put(q_i, average);
		}
		float mean_average_percision = 0;
		for(int q_i : percision_at_k_per_query.keySet())
		{
			mean_average_percision = mean_average_percision + average_percision_per_query.get(q_i);
		}
		mean_average_percision  = mean_average_percision /(float)average_percision_per_query.size();
		
		report_writer.write("MAP\n");
		report_writer.write(mean_average_percision+"\n");
		
	}

	public void CreateReport(RankedResults gt, SearchResults actual) throws IOException
	{
		Writer report_writer = new FileWriter("non_ranked_results.txt");
		CalcMeasurements(gt, actual, report_writer );
		report_writer.close();
		
		report_writer = new FileWriter("ranked_results.txt");
		CalcNDCG(gt, actual, report_writer );
		report_writer.close();
		
	}
	
	
	public void CalcNDCG(RankedResults gt, SearchResults actual, Writer report_writer) throws IOException
	{
		HashMap<Integer, Integer> document_rank_dictionary = new HashMap<Integer, Integer>();
		
		for(int q_id : gt.mResults.keySet())
		{
			Vector<RankedResults.RankedDoc> gt_doc_list = gt.mRankResults.get(q_id);
			Vector<Integer> gt_ranks = new Vector<Integer>();
			for (RankedResults.RankedDoc ranked_doc : gt_doc_list)
			{
				document_rank_dictionary.put(ranked_doc.mId, ranked_doc.mRank);
				gt_ranks.add(ranked_doc.mRank);
			}			
			
			float gt_dcg = CalcDCG(gt_ranks);
			float NDCG = 0;
			if(actual.mResults.containsKey(q_id) && (gt_dcg > 0))
			{
				Vector<Integer> result_vector = actual.mResults.get(q_id);
				Vector<Integer> gt_doc_id_list = gt.mResults.get(q_id);
				Vector<Integer> ranks =  new Vector<Integer>();
				for(int i =0; i< result_vector.size();++i)
				{
					int doc_id = result_vector.get(i);
					if(gt_doc_id_list.contains(doc_id))
					{
						ranks.add(document_rank_dictionary.get(doc_id));						
					}
					else
					{
						ranks.add(0);
					}
				}
				
				float DCG = CalcDCG(ranks);
				NDCG = (float)DCG / (float)gt_dcg;
								
			}
			else
			{
				NDCG = 0f;
			}
			report_writer.write(+q_id+","+NDCG+"\n");			
		}
	}
	
	private float CalcDCG(Vector<Integer> ranks)
	{
		float DCG = 0;
		int position = 1;
		for (int rank : ranks)
		{
			float gain = 0;
			if(position == 1)
			{
				gain = rank;
			}
			else
			{
				gain = (float)rank/(float)log2(position);
			}
			++position;
			DCG = DCG + gain;				 
		}
		
		return DCG;
	}
	

	 }

*/